
package cn.nubia.admin.sysconfig.service;

import cn.nubia.admin.sysconfig.bean.Category;
import cn.nubia.admin.sysconfig.bean.CategoryConstruct;
import cn.nubia.admin.sysconfig.bean.CategoryQuery;
import cn.nubia.admin.common.exception.NBException;
import cn.nubia.admin.common.mybatis.bean.Paged;
import cn.nubia.admin.common.mybatis.bean.Query;
import cn.nubia.admin.common.mybatis.service.BaseServiceImpl;
import cn.nubia.admin.sysconfig.bean.SystemLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * com.beta.category.service.
 * <p>User:nbc/p>
 * <p>Date:15-6-30  上午9:36</p>
 */
@Service
public class CategoryService extends BaseServiceImpl<Category> {

    @Autowired
    SystemLogService systemLogService;

    public static Map<Integer,CategoryConstruct> cache = new HashMap<>();

    /**
     * 新增分类业务接口
     * @param category
     * @return
     */
    public Category addCategory(Category category) {
        category= insert(category);
        systemLogService.log(SystemLog.ModuleTypeEnum.CATEGORYLIST, SystemLog.OperateTypeEnum.ADD, category.getId());

        return category;
    }


    public CategoryConstruct getCategoryConstruct(Integer id){
        if(id == null)return null;
        CategoryConstruct categoryConstruct = cache.get(id);
        if(categoryConstruct!=null)return categoryConstruct;
        categoryConstruct = this.constructorCategory(id);
        if(categoryConstruct != null){
            cache.put(id, categoryConstruct);
            return categoryConstruct;
        }
        return null;
    }

    public void clearCache(Integer id){
        cache.remove(id);
        Category category = get(id);
        if(category.getParentId()!=0){
            cache.remove(category.getParentId());
            List<Category> categories = getSubCategoryList(id);
            if(categories!=null){
                for(Category subCategory: categories){
                    cache.remove(subCategory.getId());
                }
            }
        }else{
            List<Category> categories = getSubCategoryList(id);
            if(categories!=null){
                for(Category subCategory: categories){
                    cache.remove(subCategory.getId());
                    List<Category> thirdCategories = getSubCategoryList(id);
                    if(thirdCategories!=null){
                        for(Category thirdCategory: thirdCategories){
                            cache.remove(thirdCategory.getId());
                        }
                    }
                }
            }
        }

    }

    /**
     * 更新分类业务接口
     * @param category
     */
    public boolean updateCategory(Category category) {
        update(category);
        clearCache(category.getId());
        systemLogService.log(SystemLog.ModuleTypeEnum.CATEGORYLIST, SystemLog.OperateTypeEnum.EDIT, category.getId());

        return true;
    }


    public Paged<Category> listForLevel(CategoryQuery categoryQuery){
        Query query = Query.build(Category.class);
        if(categoryQuery.getParentId()!=null && categoryQuery.getParentId()>=0){
            query.addEq("parentId", categoryQuery.getParentId());
        }else{
            query.addEq("parentId", 0);
        }
        query.addOrder("id", Query.DBOrder.DESC);
        query.addNotEq("state", Category.STATE_DELETE);
        query.setPaged(categoryQuery.getPageNo(), categoryQuery.getPageSize());
        Paged<Category> result =findPagedByQuery(query);
        for(Category category: result.getListData()){
            category.setHasSub(hasSubCategory(category.getId())?1:0);
        }
        return result;
    }



    /**
     * 分类分页列表业务接口
     * @param categoryQuery
     * @return
     */
    public Paged<Category> list(CategoryQuery categoryQuery) {
        if(categoryQuery.getCategoryName()!=null && !"".equals(categoryQuery.getCategoryName())){
            return findCategoriesByName(categoryQuery);
        }
        Query query = Query.build(Category.class);
        if(categoryQuery.getParentId()!=null && categoryQuery.getParentId()>=0){
            query.addEq("parentId", categoryQuery.getParentId());
        }
        if(categoryQuery.getCategoryId()!=null && categoryQuery.getCategoryId()>=0){
            query.addEq(Category.COLUMN_ID,categoryQuery.getCategoryId());
        }
        query.addOrder("id", Query.DBOrder.DESC);
        query.addNotEq("state", Category.STATE_DELETE);
        query.setPaged(categoryQuery.getPageNo(), categoryQuery.getPageSize());
        Paged<Category> result =findPagedByQuery(query);
        for(Category category: result.getListData()){
            List<Category> subCategoryList=  getSubCategoryList(category.getId());
            if(subCategoryList!=null&&subCategoryList.size()>0) {
                category.setHasSub(1);
                for (Category subCategory : subCategoryList) {
                    List<Category> subCategoryList2=  getSubCategoryList(subCategory.getId());
                    if(subCategoryList2!=null&&subCategoryList2.size()>0) {
                        subCategory.setHasSub(1);
                        subCategory.setSubCategoryList(subCategoryList2);
                    }
                }
                category.setSubCategoryList(subCategoryList);
            }
        }
        return result;
    }




    private boolean containParentCategory(List<Category> categories,Integer parentId){
        for(Category category : categories){
            if(category.getId().intValue() == parentId.intValue()) {
                return  true;
            }
        }
        return false;
    }


    private Paged<Category> findCategoriesByName(CategoryQuery categoryQuery) {
        Query query = Query.build(Category.class);
        query.addLike("categoryName", categoryQuery.getCategoryName());
        query.addOrder("id", Query.DBOrder.DESC);
        query.addNotEq("state", Category.STATE_DELETE);
        query.setPaged(categoryQuery.getPageNo(), categoryQuery.getPageSize());
        Paged<Category> result =findPagedByQuery(query);
        List<Category> categories = result.getListData();
        List<Category> newCategoryList = new ArrayList<>();
        for(Category category: categories){
            if(!containParentCategory(newCategoryList,category.getParentId())){
                Category parent = get(category.getParentId());
                parent.setHasSub(1);
                if(parent.getSubCategoryList()==null){
                    List<Category> subs = new ArrayList<>();
                    subs.add(category);
                    parent.setSubCategoryList(subs);
                }else{
                    parent.getSubCategoryList().add(category);
                }
                if(parent.getParentId().intValue() == 0){
                    newCategoryList.add(parent);
                }else{
                    if(!containParentCategory(newCategoryList,parent.getParentId())){
                        Category top = get(parent.getParentId());
                        top.setHasSub(1);
                        if(top.getSubCategoryList() == null){
                            List<Category> subs = new ArrayList<>();
                            subs.add(parent);
                            top.setSubCategoryList(subs);
                        }else{
                            top.getSubCategoryList().add(parent);
                        }
                        newCategoryList.add(top);
                    }

                }
            }
        }
        result.setListData(newCategoryList);
        return result;
    }

    private  Category makeTreeCategory(Category category){
        List<Category> subCategoryList = getSubCategoryList(category.getId());
        if(subCategoryList!=null&& subCategoryList.size()>0){
            category.setHasSub(1);
            category.setSubCategoryList(subCategoryList);
            for(Category subCategory :subCategoryList){
                subCategory.setHasSub(3);
                return makeTreeCategory(subCategory);
            }
        }

        return category;
    }
    /**
     * 删除分类
     * @param id
     */
    public boolean deleteCategory(Integer id) throws NBException{
        if(hasSubCategory(id))
            throw new NBException("拥有子分类，不能删除");
        updateState(id, Category.STATE_DELETE);
        systemLogService.log(SystemLog.ModuleTypeEnum.CATEGORYLIST, SystemLog.OperateTypeEnum.DEL, id);

        clearCache(id);
        return true;
    }

    /**
     * 获取子类列表
     * @param id
     * @return
     */
    public List<Category> getSubCategoryList(Integer id){
        Query query = new Query(Category.class);
        query.addNotEq("state", Category.STATE_DELETE);
        query.addEq("parentId",id);
        return findByQuery(query);
    }

    /**
     * 判断是否拥有子类
     * @param id
     * @return
     */
    public boolean hasSubCategory(int id){
        Query query = new Query(Category.class);
       query.addNotEq("state", Category.STATE_DELETE);
        query.addEq("parentId", id);
        int count=count(query);
        return count > 0 ? true:false;
    }

    /**
     * 更新state
     * @param id
     * @param state
     * @return
     */
    public boolean updateState(Integer id,Integer state) {
        Category category = new Category();
        category.setId(id);
        category.setState(state);
        update(category);
        return true;
    }

    /**
     * 查看分类
     * @param id
     * @return
     */
    public Category viewCategory(Integer id) {
        return get(id);
    }


    /**
     * 分类列表
     * @param categoryQuery
     * @return
     */
    public List<Category> categoryList(CategoryQuery categoryQuery) {
        Query query = new Query(Category.class);
        query.addEq("state", Category.STATE_SHOW);
        query.addEq("parentId",categoryQuery.getParentId());
        query.addEq("level",categoryQuery.getLevel());
        query.addOrder("id", Query.DBOrder.DESC);
        List<Category> result =findByQuery(query);
        for(Category category: result){
            if(hasSubCategory(category.getId())){
                category.setHasSub(1);
            }
        }
        return result;
    }

    /**
     * 分类列表
     * @param categoryId
     * @return
     */
    public CategoryConstruct constructorCategory(int categoryId) {
        if(categoryId == 0)return null;
        Category category1 = get(categoryId);
        if(category1==null)return new CategoryConstruct();
        if(category1.getParentId()==0){
            return new CategoryConstruct(categoryId,category1.getCategoryName());
        }else{
            Category category2 = get(category1.getParentId());
            if(category2.getParentId()==0){
                return new CategoryConstruct(category2.getId(),category2.getCategoryName(),
                        category1.getId(),category1.getCategoryName());
            }else {
                Category category3 = get(category2.getParentId());
                return new CategoryConstruct(category3.getId(),category3.getCategoryName(),
                        category2.getId(),category2.getCategoryName()
                        ,category1.getId(),category1.getCategoryName());
            }
        }
    }

    public boolean check(Integer id, Integer parentId, String categoryName) {
        Query query= Query.build(Category.class);
        query.addEq("id",id);
        query.addEq("parentId",parentId);
        query.addEq("categoryName",categoryName);
        return isExist(query,id);
    }
}
